﻿using System;
using System.Collections.Generic;
using System.Reflection;
using Mbs.Collections;
using Mbs.ComponentModel.Container.Context;
using Mbs.ComponentModel.Container.Metadata;

namespace Mbs.ComponentModel.Container.Injection
{
    [Serializable]
    class InspectCacheProxy:MarshalAndDisposableObject, IInspect 
    {
        private readonly IInspect RealProxy;
        private readonly IMap<Type, KeyValuePair<MemberInfo, string>[]> Cache = new ConcurrentMap<Type, KeyValuePair<MemberInfo, string>[]>();

        protected IKernel Kernel { get; set; }
        protected IComponentInfo Component { get; set; }

        public KeyValuePair<MemberInfo, string>[] Members { get; private set; }

        public InspectCacheProxy(IInspect inspect)
        {
            RealProxy = inspect;
        }



        public IInjectContext Execute(IInspectContext ctx)
        {
            var impType = ctx.Instance != null ? ctx.Instance.GetType() : ctx.Component.Implementation;

            if (Cache.ContainsKey(impType))
            {
                Members = Cache[impType];

                return new InjectContext(ctx.Kernel, ctx.Component, ctx.Instance, Members);
            }
            else
            {
                var injectCtx = RealProxy.Execute(ctx);
                Members = injectCtx.Members;

                Cache[impType] = Members;

                return injectCtx;
            }
            
        }
      
    }
}
